// Copyright (c) 2007 Robin Boerdijk. All rights reserved.
//
// This software is licensed under the terms of the Microsoft Reciprocal License as described 
// in the file LICENSE.txt, which you should have received as part of this distribution. The 
// license terms are also available at http://www.opensource.org/licenses/ms-rl.html.

#ifndef wtk_win32_h_included
#define wtk_win32_h_included

#include <windows.h>
#include <commctrl.h>

namespace wtk
{
	namespace win32
	{
		void AdjustWindowRectEx(LPRECT, DWORD, BOOL, DWORD);
		HDWP BeginDeferWindowPos(int);
		inline LRESULT CallWindowProcA(WNDPROC proc, HWND wnd, UINT m, WPARAM w, LPARAM l) { return ::CallWindowProcA(proc, wnd, m, w, l); }
		inline LRESULT CallWindowProcW(WNDPROC proc, HWND wnd, UINT m, WPARAM w, LPARAM l) { return ::CallWindowProcW(proc, wnd, m, w, l); }
		void CloseWindow(HWND wnd);
		HMENU CreateMenu();
		HMENU CreatePopupMenu();
		HWND CreateWindowExA(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
		HWND CreateWindowExW(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
		HDWP DeferWindowPos(HDWP, HWND, HWND, int, int, int, int, UINT);
		void DestroyMenu(HMENU);
		void DestroyWindow(HWND);
		inline LRESULT DispatchMessageA(const MSG *msg) { return ::DispatchMessageA(msg); }
		inline LRESULT DispatchMessageW(const MSG *msg) { return ::DispatchMessageW(msg); }
		void DrawMenuBar(HWND);
		int DrawTextExA(HDC, LPSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);
		int DrawTextExW(HDC, LPWSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);
		BOOL EnableWindow(HWND, BOOL);
		void EndDeferWindowPos(HDWP);
		inline void EnumChildWindows(HWND wnd, WNDENUMPROC proc, LPARAM l) { ::EnumChildWindows(wnd, proc, l); }
		void GetClassInfoExA(HINSTANCE, LPCSTR, LPWNDCLASSEXA);
		void GetClassInfoExW(HINSTANCE, LPCWSTR, LPWNDCLASSEXW);
		void GetClientRect(HWND, LPRECT);
		HANDLE GetClipboardData(UINT);
		void GetCursorPos(LPPOINT);
		HDC GetDC(HWND);
		inline HWND GetDesktopWindow() { return ::GetDesktopWindow(); }
		inline HMENU GetMenu(HWND wnd) { return ::GetMenu(wnd); }
		int GetMenuItemCount(HMENU);
		void GetMenuItemInfoA(HMENU, UINT, BOOL, LPMENUITEMINFOA);
		void GetMenuItemInfoW(HMENU, UINT, BOOL, LPMENUITEMINFOW);
		BOOL GetMessageA(LPMSG, HWND, UINT, UINT);
		BOOL GetMessageW(LPMSG, HWND, UINT, UINT);
		HWND GetParent(HWND);
		HGDIOBJ GetStockObject(int);
		template<typename T> T GetStockObject(int i) { return reinterpret_cast<T>(GetStockObject(i)); }
		inline HBRUSH GetSysColorBrush(int i) { return ::GetSysColorBrush(i); }
		void GetTextExtentPoint32A(HDC, LPCSTR, int, LPSIZE);
		void GetTextExtentPoint32W(HDC, LPCWSTR, int, LPSIZE);
		int GetTextFaceA(HDC, int, LPSTR);
		int GetTextFaceW(HDC, int, LPWSTR);
		HDC GetWindowDC(HWND);
		void GetWindowInfo(HWND, PWINDOWINFO);
		LONG GetWindowLongA(HWND, int);
		LONG GetWindowLongW(HWND, int);
		template<typename T> T GetWindowLongA(HWND wnd, int i) { return reinterpret_cast<T>(win32::GetWindowLongA(wnd, i)); }
		template<typename T> T GetWindowLongW(HWND wnd, int i) { return reinterpret_cast<T>(win32::GetWindowLongW(wnd, i)); }
#ifdef _WIN64
		LONG_PTR GetWindowLongPtrA(HWND, int);
		LONG_PTR GetWindowLongPtrW(HWND, int);
		template<typename T> T GetWindowLongPtrA(HWND wnd, int i) { return reinterpret_cast<T>(win32::GetWindowLongPtrA(wnd, i)); }
		template<typename T> T GetWindowLongPtrW(HWND wnd, int i) { return reinterpret_cast<T>(win32::GetWindowLongPtrW(wnd, i)); }
#else
		// GetWindowLongPtrA automatically defined by "#define GetWindowLongPtrA GetWindowLongA" in WinUser.h
		// GetWindowLongPtrW automatically defined by "#define GetWindowLongPtrW GetWindowLongW" in WinUser.h
#endif
		void GetWindowRect(HWND, LPRECT);
		int GetWindowTextA(HWND, LPSTR, int);
		int GetWindowTextW(HWND, LPWSTR, int);
		int GetWindowTextLengthA(HWND);
		int GetWindowTextLengthW(HWND);
		LPVOID GlobalLock(HGLOBAL);
		BOOL GlobalUnlock(HGLOBAL);
		void InsertMenuItemA(HMENU, UINT, BOOL, LPCMENUITEMINFOA);
		void InsertMenuItemW(HMENU, UINT, BOOL, LPCMENUITEMINFOW);
		BOOL IsClipboardFormatAvailable(UINT);
		inline BOOL IsMenu(HMENU menu) { return ::IsMenu(menu); }
		inline BOOL IsWindow(HWND wnd) { return ::IsWindow(wnd); }
		inline BOOL IsWindowEnabled(HWND wnd) { return ::IsWindowEnabled(wnd); }
		inline BOOL IsWindowVisible(HWND wnd) { return ::IsWindowVisible(wnd); }
		HCURSOR LoadCursorA(HINSTANCE, LPCSTR);
		HCURSOR LoadCursorW(HINSTANCE, LPCWSTR);
		int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT);
		int MessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);
		void OpenClipboard(HWND);
		void CloseClipboard();
		inline void PostQuitMessage(int i) { ::PostQuitMessage(i); }
		ATOM RegisterClassExA(CONST WNDCLASSEXA *);
		ATOM RegisterClassExW(CONST WNDCLASSEXW *);
		inline int ReleaseDC(HWND wnd, HDC dc) { return ::ReleaseDC(wnd, dc); }
		void RemoveWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR);
		inline HGDIOBJ SelectObject(HDC dc, HGDIOBJ obj) { return ::SelectObject(dc, obj); }
		template<typename R, typename W, typename L> R SendMessageA(HWND wnd, UINT msg, W w, L l) { return R(::SendMessageA(wnd, msg, WPARAM(w), LPARAM(l))); }
		template<typename R, typename W, typename L> R SendMessageW(HWND wnd, UINT msg, W w, L l) { return R(::SendMessageW(wnd, msg, WPARAM(w), LPARAM(l))); }
		HWND SetActiveWindow(HWND);
		void SetMenu(HWND windowHandle, HMENU menuHandle);
		void SetMenuInfo(HMENU, LPCMENUINFO);
		LONG SetWindowLongA(HWND, int, LONG);
		LONG SetWindowLongW(HWND, int, LONG);
		template<typename T> T SetWindowLongA(HWND wnd, int i, T t) { return T(win32::SetWindowLongA(wnd, i, LONG(t))); }
		template<typename T> T SetWindowLongW(HWND wnd, int i, T t) { return T(win32::SetWindowLongW(wnd, i, LONG(t))); }
#ifdef _WIN64
		LONG_PTR SetWindowLongPtrA(HWND, int, LONG_PTR);
		LONG_PTR SetWindowLongPtrW(HWND, int, LONG_PTR);
		template<typename T> T SetWindowLongPtrA(HWND wnd, int i, T t) { return T(win32::SetWindowLongPtrA(wnd, i, LONG_PTR(t))); }
		template<typename T> T SetWindowLongPtrW(HWND wnd, int i, T t) { return T(win32::SetWindowLongPtrW(wnd, i, LONG_PTR(t))); }
#else
		// SetWindowLongPtrA automatically defined by "#define SetWindowLongPtrA SetWindowLongA" in WinUser.h
		// SetWindowLongPtrW automatically defined by "#define SetWindowLongPtrW SetWindowLongW" in WinUser.h
#endif
		void SetWindowPos(HWND, HWND, int, int, int, int, UINT);
		void SetWindowSubclass(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
		inline BOOL ShowWindow(HWND wnd, int i) { return ::ShowWindow(wnd, i); }
		inline BOOL TranslateMessage(const MSG *msg) { return ::TranslateMessage(msg); }
		void UnregisterClassA(LPCSTR, HINSTANCE);
		void UnregisterClassW(LPCWSTR, HINSTANCE);
		void UpdateWindow(HWND);

		static const UINT SWP_DONOTHING = SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER
			| SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER;

	}
}

#endif